package com.clear.gateway.auth;

import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.reactor.filter.SaReactorFilter;
import cn.dev33.satoken.router.SaRouter;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * [Sa-Token 权限认证] 配置类
 * https://sa-token.cc/doc.html?code=5538d41dae0f6a75d6df6d14a8a3530e85bdd93f37af1fdb918470323608c9cb#/up/global-filter
 *
 * @author click33
 */
@Configuration
@Slf4j
public class SaTokenConfigure {

    // 注册 Sa-Token全局过滤器 
    @Bean
    public SaReactorFilter getSaReactorFilter() {
        return new SaReactorFilter()
                // 拦截地址
                .addInclude("/**")    /* 拦截全部path */
                // 开放地址
                .addExclude("/favicon.png")
                // 鉴权方法：每次访问进入
                .setAuth(obj -> {
                    log.info("---------- 进入Sa-Token全局认证 ----------- \n" + SaHolder.getRequest().getRequestPath());

                    /**
                     * SaRouter.match() 匹配函数有两个参数：
                     *  参数一：要匹配的path路由。
                     *  参数二：要执行的校验函数
                     */
                    // 登录认证 -- 拦截所有路由，并排除/user/doLogin 用于开放登录
//                    SaRouter.match("/**", "/user/doLogin", () -> StpUtil.checkLogin());
                    // 更多拦截处理方式，请参考“路由拦截式鉴权”章节 */
                    // 登录校验 -- 只有登录以后才能访问 /oss/**
                    SaRouter.match("/oss/**", r -> StpUtil.checkLogin());
                    // 登录校验 -- 只有登录以后才能访问 /subject/**
                    SaRouter.match("/subject/**", r -> StpUtil.checkLogin());
                    // 权限校验 -- 不同模块校验不同权限
                    // 匹配/subject/subject/add，除非有 subject:add 权限
                    SaRouter.match("/subject/subject/add", r -> StpUtil.checkPermission("subject:add"));

                })
                // 异常处理函数：每次认证函数发生异常时执行此函数
                .setError(e -> {
                    log.error("---------- 进入Sa-Token异常处理 -----------");
                    return SaResult.error(e.getMessage());
                });
    }
}
